package com.itfitness.bluetoothdemo

import android.annotation.SuppressLint
import android.bluetooth.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.itfitness.bluetoothdemo.databinding.ActivityMainBinding
import java.lang.Exception
import java.util.*
import kotlin.collections.ArrayList

class MainActivity : AppCompatActivity() {
    private val TAG = "BluetoothDemo"
    private val MUUID = "46e38342-aff4-4da7-9568-f5e3f7d6d2a6" //用于连接的UUID
    private var bluetoothServerSocket:BluetoothServerSocket? = null //服务端Socket
    private var bluetoothClientSocket:BluetoothSocket? = null //客户端Socket
    private var bluetoothAdapter: BluetoothAdapter? = null
    private lateinit var activityMainBinding: ActivityMainBinding
    private lateinit var openBluetoothActivityForResult:ActivityResultLauncher<Intent>
    private lateinit var deviceAdapter: BaseQuickAdapter<BluetoothDevice,BaseViewHolder>
    private val deviceList = ArrayList<BluetoothDevice>() //设备列表
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activityMainBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
        activityMainBinding.lifecycleOwner = this

        initBluetooth()

        registerActivityResultLauncher()

        registerBluetoothScan()

        initListener()

        preDeviceAdapter()

    }

    /**
     * 获取蓝牙BluetoothAdapter
     *
     *
     */
    private fun initBluetooth() {
        val bluetoothManager =  getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
        bluetoothAdapter = bluetoothManager.adapter
    }

    private fun preDeviceAdapter() {

        bluetoothAdapter?.let {
            it.bondedDevices.onEach { device->
                deviceList.add(device)
            }
        }

        deviceAdapter = object :BaseQuickAdapter<BluetoothDevice,BaseViewHolder>(R.layout.item_bluetooth,deviceList){
            override fun convert(holder: BaseViewHolder, item: BluetoothDevice) {
                val tvDeviceName = holder.getView<TextView>(R.id.tv_deviceName)
                val btConnect = holder.getView<Button>(R.id.bt_connect)
                tvDeviceName.text = item.name
                btConnect.visibility = View.VISIBLE
                when(item.bondState){
                    //未配对
                    BluetoothDevice.BOND_NONE->{
                        btConnect.text = "配对"
                    }
                    //已配对
                    BluetoothDevice.BOND_BONDED->{
                        btConnect.text = "连接"
                    }
                }
                btConnect.setOnClickListener {
                    when (item.bondState) {
                        //未配对 进行配对
                        BluetoothDevice.BOND_NONE -> {
                            item.createBond()
                        }
                        //已配对 进行连接
                        BluetoothDevice.BOND_BONDED -> {
                            connectDevice(item)
                        }
                    }
                }
            }
        }
        activityMainBinding.rvBluetooth.apply {
            layoutManager = LinearLayoutManager(this@MainActivity)
            adapter = deviceAdapter
        }
    }

    /**
     * 连接设备
     */
    private fun connectDevice(device: BluetoothDevice) {
        bluetoothClientSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(MUUID))
        bluetoothClientSocket?.let {
            Thread{
                try {
                    it.connect()
                    if(it.isConnected){
                        ToastUtils.showShort("已连接")
                        readServerData(it)
                    }else{
                        ToastUtils.showShort("未连接")
                    }
                }catch (e:Exception){}
            }.start()
        }
    }

    /**
     * 读取服务端的数据
     */
    private fun readServerData(socket: BluetoothSocket) {
        val ins = socket.inputStream
        try {
            val buffer = ByteArray(60)
            val size = ins.read(buffer)
            if(size > 0){
                val msg = String(buffer,0,size)
                LogUtils.eTag("消息",msg)
                ToastUtils.showShort(msg)
            }
            ins.close()
            socket.close()
        }catch (e:Exception){
            LogUtils.eTag("出错",e.message)
        }finally {
            ins.close()
            socket.close()
        }
    }

    /**
     * 注册扫描蓝牙的广播
     */
    private fun registerBluetoothScan() {
        registerReceiver(bluetoothScanBroadcastReceiver, IntentFilter(BluetoothDevice.ACTION_FOUND))
        registerReceiver(bluetoothScanBroadcastReceiver, IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED))
        registerReceiver(bluetoothScanBroadcastReceiver, IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED))
        registerReceiver(bluetoothScanBroadcastReceiver, IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED))
    }

    private fun initListener() {
        activityMainBinding.btOpenBluetooth.setOnClickListener {
            checkBluetooth()
        }

        activityMainBinding.btScanBluetooth.setOnClickListener {
            scanBluetooth()
        }
        activityMainBinding.btOpenService.setOnClickListener {
            openService()
        }
    }

    /**
     * 开启连接服务
     */
    private fun openService() {
        bluetoothAdapter?.let {
            if(!it.isEnabled){
                ToastUtils.showShort("请先开启蓝牙")
            }else{
                bluetoothServerSocket = it.listenUsingRfcommWithServiceRecord(TAG, UUID.fromString(MUUID))
                Thread {
                    while (true){
                        bluetoothServerSocket?.let { serverSocket->
                            val socket = serverSocket.accept()
                            val device = socket.remoteDevice
                            if(socket.isConnected){
                                device?.let {
                                    LogUtils.eTag("状态","${device.bondState}")
                                    ToastUtils.showShort("设备：${device.name} 已连接${device.bondState}")
                                }
                            }
                            sendData2Client(socket)
                        }
                    }
                }.start()
            }
        }
    }

    /**
     * 发送消息给客户端
     */
    private fun sendData2Client(socket: BluetoothSocket?) {
        socket?.let {
            val os = socket.outputStream
            try {
                val msg = "你好我是${bluetoothAdapter?.name}"
                os.write(msg.toByteArray())
                os.flush()
                os.close()
                socket.close()
            }catch (e:Exception){
                LogUtils.eTag("出错",e.message)
            }finally {
                os.close()
                socket.close()
            }
        }
    }

    /**
     * 注册请求开启蓝牙的Launcher
     */
    private fun registerActivityResultLauncher() {
        openBluetoothActivityForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result->
            if (result.resultCode == RESULT_OK) {
                ToastUtils.showShort("蓝牙开启")
            }else{
                ToastUtils.showShort("未能开启")
            }
        }
    }

    /**
     * 扫描蓝牙
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun scanBluetooth() {
        deviceList.clear()
        bluetoothAdapter?.let {
            it.bondedDevices.onEach { device->
                deviceList.add(device)
            }
        }
        deviceAdapter.notifyDataSetChanged()
        bluetoothAdapter?.startDiscovery()
    }

    /**
     * 检测是否支持蓝牙
     */
    private fun checkBluetooth() {
        if(bluetoothAdapter == null){
            ToastUtils.showShort("没有蓝牙")
            return
        }else{
            ToastUtils.showShort("有蓝牙")
            openBluetooth()
        }
    }

    /**
     * 请求打开蓝牙
     */
    private fun openBluetooth() {
        bluetoothAdapter?.let {
            if(!it.isEnabled){
                ToastUtils.showShort("即将开启蓝牙")
                val openBluetoothIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
                openBluetoothActivityForResult.launch(openBluetoothIntent)
            }else{
                ToastUtils.showShort("蓝牙以开启")
            }
        }
    }

    private val bluetoothScanBroadcastReceiver = object :BroadcastReceiver(){
        @SuppressLint("NotifyDataSetChanged")
        override fun onReceive(context: Context?, intent: Intent?) {
            intent?.let {
                when(it.action){
                    //开始扫描
                    BluetoothAdapter.ACTION_DISCOVERY_STARTED->{
                        ToastUtils.showShort("开始扫描")
                        LogUtils.eTag("蓝牙","开始扫描")
                    }
                    //扫描到设备
                    BluetoothDevice.ACTION_FOUND->{
                        it.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)?.let { device->
                            device.name?.let {
                                LogUtils.eTag("蓝牙",device.name)
                                deviceList.add(device)
                                deviceAdapter.notifyDataSetChanged()
                            }
                        }
                    }
                    //扫描结束
                    BluetoothAdapter.ACTION_DISCOVERY_FINISHED->{
                        ToastUtils.showShort("扫描结束")
                        LogUtils.eTag("蓝牙",deviceList)
                    }
                    BluetoothDevice.ACTION_BOND_STATE_CHANGED->{
                        it.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)?.let { device->

                            if(device.bondState == BluetoothDevice.BOND_BONDED){
                                device.name?.let {
                                    ToastUtils.showShort("${it}已配对")
                                    deviceAdapter.notifyDataSetChanged()
                                }
                            }
                        }
                    }
                    else -> {
                        ToastUtils.showShort("其他")
                        LogUtils.eTag("蓝牙","其他")
                    }
                }
            }
        }
    }
}